Airitme bundle purchase#71
Open
abubakar508 wants to merge 2 commits intonutcas3:mainfrom
Open
Conversation
OPc must be computed as AES-128(K, OP) XOR OP, not just AES-128(K, OP).
The missing XOR step produced incorrect OPc values incompatible with any
standard Milenage implementation.
- Add XOR of encrypted block with OP in generateOPc()
- Add Milenage f1–f5 helper functions (runMilenage, xorBytes,
rotateLeft)
feat(subscriber): add SQN field for 3GPP AKA replay protection
Sequence number (SQN) is required by the Milenage AKA protocol to
prevent replay attacks. It is incremented atomically on each auth
vector generation.
feat(handlers): expose AuC auth-vector endpoint
Adds POST /api/v1/auc/:imsi/auth-vector for HSS/MME to request
authentication vectors during subscriber attach procedures.
- AuCHandler struct with SubscriberService dependency
- Returns { rand, xres, ck, ik, autn } as hex strings
- Returns 404 if IMSI not found, 500 on crypto/DB failure
- Register route in router
feat(auc): implement Authentication Center with Milenage AKA
Adds GenerateAuthVector() which produces a full 3GPP AKA authentication
vector (RAND, XRES, CK, IK, AUTN) for a given IMSI using the Milenage
algorithm (3GPP TS 35.205/206).
- Load subscriber K and OPc from DB by IMSI
- Atomically increment SQN via UPDATE … RETURNING (no race condition)
- Generate 16-byte RAND via crypto/rand
- Run Milenage f1–f5 to derive XRES, CK, IK, AK, MAC-A
- Construct AUTN = (SQN XOR AK) || AMF || MAC-A
Files changed:
M apps/api-server/internal/services/subscriber_auth.go
A apps/api-server/internal/services/subscriber_auc.go
A apps/api-server/internal/handlers/auc_handler.go
M apps/api-server/internal/models/subscriber.go
A migrations/00019_add_subscriber_sqn.sql
add: new migration for teh sequencing number attached to the
Authentication Center (AuC)
- Add SQN int64 field to models.Subscriber (gorm:"default:0")
- Add migration 00019_add_subscriber_sqn.sql:
ALTER TABLE subscribers ADD COLUMN sqn BIGINT NOT NULL DEFAULT 0
access fix(errors): add BundleNotFound, BundleAlreadyActive, InvalidBundleConfig variants with correct HTTP status mappings (404, 409, 400)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(charging/types): add Bundle, ActiveBundle, and AirtimeBalance types
Adds all data models required for airtime and bundle distribution:
amount_unconverted, is_active)
remaining_allowances) with Redis FromRedisValue/ToRedisArgs impls
fix(charging): make RatingPlansRepo pool pub(crate) for bundle service access
fix(errors): add BundleNotFound, BundleAlreadyActive, InvalidBundleConfig
variants with correct HTTP status mappings (404, 409, 400)
feat(charging): implement airtime service
Adds airtime management on ChargingEngine via airtime_service.rs:
Redis airtime:home:{imsi} or airtime:roaming:{imsi}
returns InsufficientAirtime if balance < requested
feat(charging): implement bundle service with airtime-funded purchase
Adds bundle lifecycle management on ChargingEngine via bundle_service.rs:
maintains bundle:active:set:{imsi} Redis Set for O(1) lookup,
writes subscriber_bundles row to PostgreSQL
amount_unconverted from airtime balance then activates bundle
both MSISDNs to IMSIs, deducts from sender airtime, activates on
recipient
feat(charging): register airtime_service and bundle_service modules
Adds pub mod declarations to apps/charging-engine/src/charging.rs so
rust-analyzer and the compiler can resolve the new files.
feat(handlers): add airtime and bundle HTTP handlers
handlers/airtime.rs:
handlers/bundles.rs:
Updates handlers/mod.rs with pub mod and pub use for both new modules.
feat(routes): register airtime and bundle routes in protected section
All new routes sit inside the auth_middleware + GovernorLayer stack,
inheriting rate limiting and JWT authentication automatically.
feat(migrations): add bundles, subscriber_bundles, airtime tables
00019_init_bundles.sql
columns (data_bytes, voice_seconds, sms_count, roaming_data_bytes),
validity_days, priority, amount_unconverted, is_active
00020_init_subscriber_bundles.sql
bundles.bundle_id, activated_at, expires_at, remaining allowance
columns for deduction tracking
00021_init_airtime_balances.sql
last_updated — durable source of truth synced from Redis
00022_init_airtime_transactions.sql
bundle_purchase/gift_sent/gift_received), seconds_delta, bundle_id,
created_at — full audit trail
00023_alter_usage_records_charging_source.sql
and subscriber_bundle_id INTEGER for billing reconciliation
Added airtime table migraiton